// Email.cpp: implementation of the CEmail class.
//
//////////////////////////////////////////////////////////////////////

#include "Email.h"
#include "MyParse.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CEmail::CEmail()
{

}

CEmail::~CEmail()
{

}

void CEmail::SetFrom(const std::string &from)
{
	m_strHeader = "";
	//
	MyParse pa(from, "<>");
	m_From.alias = pa.getsplit();
	m_From.addr = pa.getsplit();
}

void CEmail::SetFrom(const std::string &alias, const std::string& addr)
{
	m_strHeader = "";
	//
	m_From.alias = alias;
	m_From.addr = addr;
}

void CEmail::SetTo(const std::string &to, ToType type/* = TO*/)
{
	MyParse pa(to, ",");

	for (std::string str(pa.getsplit()); 
		!str.empty(); str = pa.getsplit())
	{
			int lo = str.find('<');
			int hi = str.find('>');

			std::string alias, addr;
			if (lo >= 0 && hi > lo )
			{
				alias = str.substr(0, lo);
				addr = str.substr(lo + 1, hi - lo - 1);
			} 
			else
			{
				addr = str;
			}
			
			trimspace(alias);
			trimspace(addr);

			AddTo(alias, addr, type);
	}
}

void CEmail::SetCc(const std::string &cc)
{
	SetTo(cc, CC);
}

void CEmail::SetBcc(const std::string &bcc)
{
	SetTo(bcc, BCC);
}

void CEmail::SetSubject(const std::string& subject)
{
	m_strHeader = "";
	m_strSubject = subject;
}

void CEmail::SetContent(const std::string &txt)
{
	m_strContent = txt;
}

void CEmail::SetHeader(const std::string &header)
{
	m_strHeader = header;
}

void CEmail::AddTo(const std::string &alias, const std::string &addr, ToType type/* = CEmail::TO*/)
{
	m_strHeader = "";

	To to;
	to.alias = alias;
	to.addr = addr;
	to.type = type;

	m_vToList.push_back(to);
}

void CEmail::AddCc(const std::string &alias, const std::string &addr)
{
	AddTo(alias, addr, CEmail::CC);
}

void CEmail::AddBcc(const std::string &alias, const std::string &addr)
{
	AddTo(alias, addr, CEmail::BCC);
}

void CEmail::GenerateHeader()
{
	m_strHeader = "";

	m_strHeader += "From: " + m_From.alias + "<" + m_From.addr + ">\r\n";
	m_strHeader += "Subject: " + m_strSubject + "\r\n";

	std::string to, cc, bcc;
	for (int i=0; i < m_vToList.size(); i++)
	{
		switch (m_vToList[i].type)
		{
		case TO:
			to += "\"" + m_vToList[i].alias + "\" ";
			to += "<" + m_vToList[i].addr + ">, ";
			break;
		case CC:
			cc += "\"" + m_vToList[i].alias + "\" ";
			cc += "<" + m_vToList[i].addr + ">, ";
			break;
		case BCC:
			bcc += "\"" + m_vToList[i].alias + "\" ";
			bcc += "<" + m_vToList[i].addr + ">, ";
			break;
		default:
			break;
		}
	}

	m_strHeader += "To: " + to + "\r\n";
	if(!cc.empty())
		m_strHeader += "Cc: " + cc + "\r\n";
//	if(!bcc.IsEmpty())
//		m_strHeader += "Bcc: " + bcc + "\r\n";

}

std::string CEmail::GetHeader()
{
	if(m_strHeader.empty())
		GenerateHeader();

	return m_strHeader;
}

std::string CEmail::GetContent()
{
	return m_strContent;
}

CEmail::From CEmail::GetFrom()
{
	return m_From;
}

CEmail::To CEmail::GetFirstTo()
{
	m_nCurTo = 0;
	
	return GetCurTo();
}

CEmail::To CEmail::GetCurTo()
{
	if(m_nCurTo >=0 && m_nCurTo < m_vToList.size())
		return m_vToList[m_nCurTo];

	To to;
	return to;
}

CEmail::To CEmail::GetNextTo()
{
	if(m_nCurTo < m_vToList.size())
		m_nCurTo++;
	
	return GetCurTo();
}

void CEmail::GetData(std::string& data)
{
	data = GetHeader() + "\r\n\r\n";
	data += GetContent() + "\r\n\r\n";
}

std::string trim(std::string& s,const std::string& drop/* = " "*/)
{
	std::string r=s.erase(s.find_last_not_of(drop)+1);
	return r.erase(0,r.find_first_not_of(drop));
}

std::string trimspace(std::string& s)
{
	std::string::size_type pos = 0;
	for( ; pos < s.size(); )
	{
		if( isspace(s[pos]) )
			s.erase(pos, 1);
		else
			break;
	} 
	
	for( pos = s.size() -1; pos >= 0; pos = s.size() -1 )
	{
		if( isspace(s[pos]) )
			s.erase(pos, 1);
		else
			break;
	} 

	return s;
}